#include "TitleBar.h"

#include <QHBoxLayout>
#include <QPainter>

#define BUTTON_HEIGHT 27 // 按钮高度
#define BUTTON_WIDTH 27  // 按钮宽度
#define TITLE_HEIFHT 27  // 标题栏高度

TitleBar::TitleBar(QWidget *parent)
    : QWidget(parent), isPressed(false), buttonType(MIN_MAX_BUTTON)
{
    initControl();
    initConnections();
    loadStyleSheet("title");
}

TitleBar::~TitleBar()
{
}

/// <summary>
/// 初始化控件
/// </summary>
void TitleBar::initControl()
{
    icon = new QLabel(this);
    titleContent = new QLabel(this);

    btnMin = new QPushButton(this);
    btnMax = new QPushButton(this);
    btnRestore = new QPushButton(this);
    btnClose = new QPushButton(this);

    // 设置大小
    QSize sizeBtn(BUTTON_WIDTH, BUTTON_HEIGHT);
    btnMin->setFixedSize(sizeBtn);
    btnMax->setFixedSize(sizeBtn);
    btnRestore->setFixedSize(sizeBtn);
    btnClose->setFixedSize(sizeBtn);

    // 设置对象名
    titleContent->setObjectName("TitleContent");
    btnMin->setObjectName("ButtonMin");
    btnMax->setObjectName("ButtonMax");
    btnRestore->setObjectName("ButtonRestore");
    btnClose->setObjectName("ButtonClose");

    // 设置布局
    layout = new QHBoxLayout(this);
    addLayout = new QHBoxLayout(this);
    layout->addWidget(icon);
    layout->addWidget(titleContent);

    layout->addLayout(addLayout);

    layout->addWidget(btnMin);
    layout->addWidget(btnRestore);
    layout->addWidget(btnMax);
    layout->addWidget(btnClose);
    btnRestore->setVisible(false);

    layout->setContentsMargins(5, 0, 0, 0); // 设置布局的间隙
    layout->setSpacing(0);                  // 设置部件间的间隙

    // 设置大小策略，左右扩展，上下固定
    titleContent->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    // 设置固定高度
    setFixedHeight(TITLE_HEIFHT);
    // 窗体风格无边框
    setWindowFlags(Qt::FramelessWindowHint);
}

bool TitleBar::addButton(QAbstractButton *button)
{
    this->addLayout->addWidget(button);

    return true;
}

/// <summary>
/// 信号与槽的连接
/// </summary>
void TitleBar::initConnections()
{
    connect(btnMin, SIGNAL(clicked()), this, SLOT(onButtonMinClicked()));
    connect(btnRestore, SIGNAL(clicked()), this, SLOT(onButtonRestoreClicked()));
    connect(btnMax, SIGNAL(clicked()), this, SLOT(onButtonMaxClicked()));
    connect(btnClose, SIGNAL(clicked()), this, SLOT(onButtonCloseClicked()));
}

/// <summary>
/// 设置标题栏的图标
/// </summary>
/// <param name="filePath">路径</param>
void TitleBar::setTitleIcon(const QString &filePath)
{
    QPixmap titleIcon(filePath);
    icon->setFixedSize(QSize(height() - 10, height() - 10));
    icon->setScaledContents(true);
    icon->setPixmap(titleIcon);
}

/// <summary>
/// 设置标题栏内容
/// </summary>
/// <param name="titleContent"></param>
void TitleBar::setTitleContent(const QString &titleContent)
{
    this->titleContent->setText(titleContent);
    this->titleContentStr = titleContent;
}

/// <summary>
/// 设置标题栏长度
/// </summary>
/// <param name="width"></param>
void TitleBar::setTitleWidth(int width)
{
    setFixedWidth(width);
}

void TitleBar::setButtonType(ButtonType buttonType)
{
    this->buttonType = buttonType;

    // 设置不可见
    btnRestore->setVisible(false);
    btnClose->setVisible(true);

    switch (buttonType)
    {
    case MIN_BUTTON:
    {
        btnMax->setVisible(false);
    }
    break;

    case MIN_MAX_BUTTON:
        break;

    case ONLY_CLOSE_BUTTON:
    {
        btnMax->setVisible(false);
        btnMin->setVisible(false);
    }
    break;

    default:
        break;
    }
}

// 绘图事件
void TitleBar::painEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPainterPath pathBack;
    pathBack.setFillRule(Qt::WindingFill);                         // 设置填充规则
    pathBack.addRoundedRect(QRect(0, 0, width(), height()), 3, 3); // 添加圆角矩形到绘图路径
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

    // 当窗口最大化或还原后，窗口长度发生改变，标题栏相应做出改变
    if (width() != parentWidget()->width())
    {
        setFixedWidth(parentWidget()->width());
    }

    QWidget::paintEvent(event);
}

void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    // 只有存在最大化、最小化按钮才有效
    if (buttonType == MIN_MAX_BUTTON)
    {
        if (btnMax->isVisible())
        {
            onButtonMaxClicked();
        }
        else
        {
            onButtonRestoreClicked();
        }
    }

    QWidget::mouseDoubleClickEvent(event);
}

void TitleBar::mousePressEvent(QMouseEvent *event)
{
    if (buttonType == MIN_MAX_BUTTON)
    {
        if (this->btnMax->isVisible())
        {
            isPressed = true;
            startMovePos = event->globalPos(); // 事件发生时鼠标所在位置
        }
    }
    else
    {
        isPressed = true;
        startMovePos = event->globalPos(); // 事件发生时鼠标所在位置
    }
    QWidget::mousePressEvent(event);
}

void TitleBar::mouseMoveEvent(QMouseEvent *event)
{
    if (enable_move)
    {
        if (isPressed)
        {
            QPoint movePoint = event->globalPos() - startMovePos;
            QPoint widgetPos = parentWidget()->pos();
            startMovePos = event->globalPos();

            auto x = widgetPos.x() + movePoint.x();
            auto y = widgetPos.y() + movePoint.y();
            parentWidget()->move(x, y);
        }
    }
}

void TitleBar::enableMove(bool enable)
{
    enable_move = enable;
}

void TitleBar::showButtonMax()
{
    btnRestore->setVisible(false);
    btnMax->setVisible(true);
}

void TitleBar::showButtonRestore()
{
    btnRestore->setVisible(true);
    btnMax->setVisible(false);
}

void TitleBar::mouseReleaseEvent(QMouseEvent *event)
{
    isPressed = false;
    QWidget::mouseReleaseEvent(event);
}

// 加载样式表
void TitleBar::loadStyleSheet(const QString &sheetName)
{
    QFile file(":/css/" + sheetName + ".css");
    file.open(QFile::ReadOnly);
    if (file.isOpen())
    {
        QString styleSheet = this->styleSheet();
        styleSheet += QLatin1String(file.readAll());
        setStyleSheet(styleSheet);
    }
}

void TitleBar::onButtonMinClicked()
{
    emit signalButtonMinClicked();
}
void TitleBar::onButtonRestoreClicked()
{
    showButtonMax();
    emit signalButtonRestoreClicked();
}
void TitleBar::onButtonMaxClicked()
{
    showButtonRestore();
    emit signalButtonMaxClicked();
}
void TitleBar::onButtonCloseClicked()
{
    emit signalButtonCloseClicked();
}
